/**
 * 网络相关工具
 * @author Copyright MySpace, Inc. 2008
 * ibio 整理、修改
 * 2009-3-10 21:17
 */
package com.ibio8.net {
	import com.ibio8.utils.StringUtil;
	
	import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.URLLoader;
    import flash.net.URLRequestMethod;
    import flash.net.URLVariables;
    import flash.net.URLRequest;
    import flash.net.URLLoaderDataFormat;
	/**
	 * 网络相关工具。
	 * 
	 * <p>
	 * 加载数据，通信等相关方法。
	 * </p>
	 */
	public class NetUtil {
		/** @private **/
		/**
		 * 这里用一个 Object 将所有的 URLLoader 句柄保存，
		 * 用于当重复加载某个时先 close 当前的 URLLoader
		 */
		static protected var m_loaderMap:Object = new Object();
		
		/**
		 * 获取指定 url 的数据
		 * @param	url				指定 url
		 * @param	args			参数
		 * @param	onResult		成功回调函数
		 * @param	onError			失败回调函数
		 * @param	usePost			是否使用 POST 方式
		 * @param	isBinary		是否是二进制
		 * @param	timestamp		自定义时间戳（小于 0：不设置；等于 0：取时间戳；大于 0：取自定义值）
		 */
		public static function getData(url:String, args:URLVariables = null, onResult:Function = null, onError:Function = null, usePost:Boolean = false, isBinary:Boolean = false, timestamp:int = -1):URLLoader {
			var loader:URLLoader;
			var request:URLRequest;
			url = StringUtil.trim(url);
			//先关闭之前的
			destroy(url, args);
			loader = new URLLoader();
			if (isBinary) {
				loader.dataFormat = URLLoaderDataFormat.BINARY;
			}
			//保存当前的 loader 句柄
			m_loaderMap[getUrlKey(url, args)] = loader;
			if (timestamp > 0) {
				url = (url.indexOf("?") > -1) ? (url + "&timestamp=" + timestamp) : (url + "?timestamp=" + timestamp);
			}else if (timestamp == 0) {
				//加上随机时间戳
				url = (url.indexOf("?") > -1) ? (url + "&timestamp=" + new Date().getTime()) : (url + "?timestamp=" + new Date().getTime());
			}
			request = new URLRequest(url);
			request.method = usePost ? URLRequestMethod.POST : URLRequestMethod.GET;
			//如果是 get 且有参数，则重新覆盖 url 属性，将参数放到后面
			if ((!usePost) && args) {
				request.url = (url.indexOf("?") > -1) ? (url + "&" + args.toString()) : (url + "?" + args.toString());
			}else {
				request.data = args;
			}
			//返回回调函数
			//注意：变量类型为 function 的判空检测只能判断是否等于某个具体空值
			if (onResult != null) {
				loader.addEventListener(Event.COMPLETE, onResult, false, 0, true);
			}
			//错误回调函数
			if (onError != null) {
				loader.addEventListener(IOErrorEvent.IO_ERROR, onError, false, 0, true);
				loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError, false, 0, true);
			}
			try {
				loader.load(request);
			}catch (e:Error) {
				trace("NetUtil::getData/loader.load()->", e.message);
			}
			return loader;
		}
		
		/**
		 * 销毁指定 url 正在获取的数据
		 * @param	url		指定的 url
		 * @param	args	此 url 所携带的参数
		 */
		public static function destroy(urlOrLoader:Object, args:URLVariables = null):void {
			var urlKey:String;
			var loader:URLLoader;
			if (urlOrLoader is String) {
				urlKey = getUrlKey(urlOrLoader as String, args);
				loader = m_loaderMap[urlKey];
			}else if (urlOrLoader is URLLoader) {
				loader = urlOrLoader as URLLoader;
			}
			//如果当前 key 存在，则停止加载
			if (loader) {
				try {
					loader.close();
				}catch (e:Error) {
					trace("NetUtil::destroy()->", e.message);
				}
			}
		}
		
		/** @private **/
		public static function getUrlKey(url:String, args:URLVariables = null):String {
			var urlKey:String;
			if (url && args) {
				if (url.indexOf("?") > -1) {
					urlKey = url + "&" + args.toString();
				}else {
					urlKey = url + "?" + args.toString();
				}
			}else {
				urlKey = url;
			}
			return urlKey;
		}
	}
}